import { useEffect, useMemo, useState } from 'react';
import {
  Alert,
  Image,
  KeyboardAvoidingView,
  Platform,
  Pressable,
  ScrollView,
  StyleSheet,
  TextInput,
  View,
} from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import { ResizeMode, Video } from 'expo-av';
import { useLocalSearchParams, useRouter } from 'expo-router';

import { ThemedButton } from '@/components/themed-button';
import { IconButton } from '@/components/icon-button';
import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view';
import { ZoomImageModal } from '@/components/zoom-image-modal';
import { Colors } from '@/constants/theme';
import { useColorScheme } from '@/hooks/use-color-scheme';
import { useTranslation } from '@/localization/i18n';
import { dbPromise, initCoreTables } from '@/services/db';

type FieldRow = {
  id: number;
  name: string | null;
  area_ha: number | null;
  notes: string | null;
  photo_uri: string | null;
  created_at: string | null;
  updated_at: string | null;
};

type FieldMediaRow = {
  uri: string | null;
};

export default function FieldDetailScreen() {
  const { t } = useTranslation();
  const router = useRouter();
  const { id } = useLocalSearchParams<{ id?: string | string[] }>();
  const fieldId = Number(Array.isArray(id) ? id[0] : id);
  const theme = useColorScheme() ?? 'light';
  const palette = Colors[theme];

  const [loading, setLoading] = useState(true);
  const [status, setStatus] = useState('');
  const [saving, setSaving] = useState(false);
  const [showSaved, setShowSaved] = useState(false);
  const [name, setName] = useState('');
  const [areaHa, setAreaHa] = useState('');
  const [notes, setNotes] = useState('');
  const [mediaUris, setMediaUris] = useState<string[]>([]);
  const [activeUri, setActiveUri] = useState<string | null>(null);
  const [errors, setErrors] = useState<{ name?: string; area?: string }>({});
  const [zoomUri, setZoomUri] = useState<string | null>(null);

  useEffect(() => {
    let isActive = true;

    async function loadField() {
      if (!Number.isFinite(fieldId)) {
        setStatus(t('fields.empty'));
        setLoading(false);
        return;
      }
      try {
        await initCoreTables();
        const db = await dbPromise;
        const rows = await db.getAllAsync<FieldRow>(
          'SELECT id, name, area_ha, notes, photo_uri, created_at, updated_at FROM fields WHERE id = ? LIMIT 1;',
          fieldId
        );
        if (!isActive) return;
        const field = rows[0];
        if (!field) {
          setStatus(t('fields.empty'));
          setLoading(false);
          return;
        }
        setName(field.name ?? '');
        setAreaHa(field.area_ha !== null ? String(field.area_ha) : '');
        setNotes(field.notes ?? '');
        const mediaRows = await db.getAllAsync<FieldMediaRow>(
          'SELECT uri FROM field_media WHERE field_id = ? ORDER BY created_at ASC;',
          fieldId
        );
        const media = uniqueMediaUris([
          ...(mediaRows.map((row) => row.uri).filter(Boolean) as string[]),
          ...(normalizeMediaUri(field.photo_uri) ? [normalizeMediaUri(field.photo_uri) as string] : []),
        ]);
        setMediaUris(media);
        setActiveUri(media[0] ?? normalizeMediaUri(field.photo_uri));
        setStatus('');
      } catch (error) {
        if (isActive) setStatus(`Error: ${String(error)}`);
      } finally {
        if (isActive) setLoading(false);
      }
    }

    loadField();
    return () => {
      isActive = false;
    };
  }, [fieldId, t]);

  const inputStyle = [
    styles.input,
    {
      borderColor: palette.border,
      backgroundColor: palette.input,
      color: palette.text,
    },
  ];

  async function handleUpdate() {
    if (!Number.isFinite(fieldId)) return;
    const trimmedName = name.trim();
    const area = areaHa.trim() ? Number(areaHa) : null;
    const nextErrors: { name?: string; area?: string } = {};
    if (!trimmedName) {
      nextErrors.name = t('fields.nameRequired');
    }
    if (areaHa.trim() && !Number.isFinite(area)) {
      nextErrors.area = t('fields.areaInvalid');
    }
    setErrors(nextErrors);
    if (Object.keys(nextErrors).length > 0) {
      return;
    }
    try {
      setSaving(true);
      const db = await dbPromise;
      const now = new Date().toISOString();
      const primaryUri = mediaUris[0] ?? normalizeMediaUri(activeUri);
      await db.runAsync(
        'UPDATE fields SET name = ?, area_ha = ?, notes = ?, photo_uri = ?, updated_at = ? WHERE id = ?;',
        trimmedName,
        area,
        notes.trim() || null,
        primaryUri ?? null,
        now,
        fieldId
      );
      await db.runAsync('DELETE FROM field_media WHERE field_id = ?;', fieldId);
      const mediaToInsert = uniqueMediaUris([
        ...mediaUris,
        ...(normalizeMediaUri(activeUri) ? [normalizeMediaUri(activeUri) as string] : []),
      ]);
      for (const uri of mediaToInsert) {
        await db.runAsync(
          'INSERT INTO field_media (field_id, uri, media_type, created_at) VALUES (?, ?, ?, ?);',
          fieldId,
          uri,
          isVideoUri(uri) ? 'video' : 'image',
          now
        );
      }
      setStatus(t('fields.saved'));
      setShowSaved(true);
      setTimeout(() => {
        setShowSaved(false);
        setStatus('');
      }, 1800);
    } catch (error) {
      setStatus(`Error: ${String(error)}`);
    } finally {
      setSaving(false);
    }
  }

  function confirmDelete() {
    Alert.alert(
      t('fields.deleteTitle'),
      t('fields.deleteMessage'),
      [
        { text: t('fields.cancel'), style: 'cancel' },
        {
          text: t('fields.delete'),
          style: 'destructive',
          onPress: async () => {
            const db = await dbPromise;
            await db.runAsync('DELETE FROM field_media WHERE field_id = ?;', fieldId);
            await db.runAsync('DELETE FROM fields WHERE id = ?;', fieldId);
            router.back();
          },
        },
      ]
    );
  }

  const previewUri = useMemo(() => normalizeMediaUri(activeUri), [activeUri]);

  return (
    <ThemedView style={[styles.container, { backgroundColor: palette.background }]}>
      <KeyboardAvoidingView
        behavior={Platform.OS === 'ios' ? 'padding' : undefined}
        style={styles.keyboardAvoid}>
        <ScrollView contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled">
          <ThemedText type="title">{t('fields.edit')}</ThemedText>
          {status && !showSaved ? <ThemedText>{status}</ThemedText> : null}

          <ThemedText>
            {t('fields.name')}
            <ThemedText style={styles.requiredMark}> *</ThemedText>
          </ThemedText>
          <TextInput
            value={name}
            onChangeText={(value) => {
              setName(value);
              if (errors.name) setErrors((prev) => ({ ...prev, name: undefined }));
            }}
            placeholder={t('fields.name')}
            placeholderTextColor={palette.placeholder}
            style={inputStyle}
          />
          {errors.name ? <ThemedText style={styles.errorText}>{errors.name}</ThemedText> : null}

          <ThemedText>{t('fields.area')}</ThemedText>
          <TextInput
            value={areaHa}
            onChangeText={(value) => {
              setAreaHa(value);
              if (errors.area) setErrors((prev) => ({ ...prev, area: undefined }));
            }}
            placeholder={t('fields.areaPlaceholder')}
            placeholderTextColor={palette.placeholder}
            style={inputStyle}
            keyboardType="decimal-pad"
          />
          {errors.area ? <ThemedText style={styles.errorText}>{errors.area}</ThemedText> : null}

          <ThemedText>{t('fields.notes')}</ThemedText>
          <TextInput
            value={notes}
            onChangeText={setNotes}
            placeholder={t('fields.notesPlaceholder')}
            placeholderTextColor={palette.placeholder}
            style={inputStyle}
            multiline
          />

          <ThemedText>{t('fields.addMedia')}</ThemedText>
          {previewUri ? (
            isVideoUri(previewUri) ? (
              <Video
                source={{ uri: previewUri }}
                style={styles.mediaPreview}
                useNativeControls
                resizeMode={ResizeMode.CONTAIN}
              />
            ) : (
              <Pressable onPress={() => setZoomUri(previewUri)}>
                <Image source={{ uri: previewUri }} style={styles.mediaPreview} resizeMode="contain" />
              </Pressable>
            )
          ) : (
            <ThemedText style={styles.photoPlaceholder}>{t('fields.noPhoto')}</ThemedText>
          )}

          {mediaUris.length > 0 ? (
            <ScrollView horizontal showsHorizontalScrollIndicator={false} style={styles.mediaStrip}>
              {mediaUris.map((uri) => (
                <Pressable key={uri} style={styles.mediaChip} onPress={() => setActiveUri(uri)}>
                  {isVideoUri(uri) ? (
                    <View style={styles.videoThumb}>
                      <ThemedText style={styles.videoThumbText}>▶</ThemedText>
                    </View>
                  ) : (
                    <Image source={{ uri }} style={styles.mediaThumb} resizeMode="cover" />
                  )}
                  <Pressable
                    style={styles.mediaRemove}
                    onPress={(event) => {
                      event.stopPropagation();
                      setMediaUris((prev) => {
                        const next = prev.filter((item) => item !== uri);
                        setActiveUri((current) => (current === uri ? next[0] ?? null : current));
                        return next;
                      });
                    }}>
                    <ThemedText style={styles.mediaRemoveText}>×</ThemedText>
                  </Pressable>
                </Pressable>
              ))}
            </ScrollView>
          ) : null}

          <View style={styles.photoRow}>
            <ThemedButton
              title={t('fields.pickFromGallery')}
              onPress={() =>
                handlePickMedia((uris) => {
                  if (uris.length === 0) return;
                  setMediaUris((prev) => uniqueMediaUris([...prev, ...uris]));
                  setActiveUri((prev) => prev ?? uris[0]);
                })
              }
              variant="secondary"
            />
            <ThemedButton
              title={t('fields.takeMedia')}
              onPress={() =>
                handleTakeMedia((uri) => {
                  if (!uri) return;
                  setMediaUris((prev) => uniqueMediaUris([...prev, uri]));
                  setActiveUri((prev) => prev ?? uri);
                })
              }
              variant="secondary"
            />
          </View>

          <View style={styles.actions}>
            <IconButton
              name="trash"
              onPress={confirmDelete}
              accessibilityLabel={t('fields.delete')}
              variant="danger"
            />
            <View style={styles.updateGroup}>
              {showSaved ? <ThemedText style={[styles.inlineToastText, { color: palette.success }]}>{t('fields.saved')}</ThemedText> : null}
              <ThemedButton
                title={saving ? t('fields.saving') : t('fields.update')}
                onPress={handleUpdate}
                disabled={saving}
              />
            </View>
          </View>
        </ScrollView>
      </KeyboardAvoidingView>
      <ZoomImageModal uri={zoomUri} visible={Boolean(zoomUri)} onClose={() => setZoomUri(null)} />
    </ThemedView>
  );
}

async function handlePickMedia(onAdd: (uris: string[]) => void) {
  const result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: getMediaTypes(),
    quality: 1,
    allowsMultipleSelection: true,
    selectionLimit: 0,
  });
  if (result.canceled) return;
  const uris = (result.assets ?? []).map((asset) => asset.uri).filter(Boolean) as string[];
  if (uris.length === 0) return;
  onAdd(uris);
}

async function handleTakeMedia(onAdd: (uri: string | null) => void) {
  const permission = await ImagePicker.requestCameraPermissionsAsync();
  if (!permission.granted) {
    return;
  }
  const result = await ImagePicker.launchCameraAsync({
    mediaTypes: getMediaTypes(),
    quality: 1,
  });
  if (result.canceled) return;
  const asset = result.assets[0];
  onAdd(asset.uri);
}

function getMediaTypes() {
  const mediaType = (ImagePicker as {
    MediaType?: { Image?: unknown; Images?: unknown; Video?: unknown; Videos?: unknown };
  }).MediaType;
  const imageType = mediaType?.Image ?? mediaType?.Images;
  const videoType = mediaType?.Video ?? mediaType?.Videos;
  if (imageType && videoType) {
    return [imageType, videoType];
  }
  return imageType ?? videoType ?? ['images', 'videos'];
}

function isVideoUri(uri: string) {
  return /\.(mp4|mov|m4v|webm|avi|mkv)(\?.*)?$/i.test(uri);
}

function normalizeMediaUri(uri?: string | null) {
  if (typeof uri !== 'string') return null;
  const trimmed = uri.trim();
  return trimmed ? trimmed : null;
}

function uniqueMediaUris(uris: string[]) {
  const seen = new Set<string>();
  const result: string[] = [];
  for (const uri of uris) {
    if (!uri || seen.has(uri)) continue;
    seen.add(uri);
    result.push(uri);
  }
  return result;
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  keyboardAvoid: {
    flex: 1,
  },
  content: {
    padding: 16,
    gap: 10,
    paddingBottom: 40,
  },
  input: {
    borderRadius: 10,
    borderWidth: 1,
    paddingHorizontal: 12,
    paddingVertical: 10,
    fontSize: 15,
  },
  requiredMark: {
    color: '#C0392B',
    fontWeight: '700',
  },
  errorText: {
    color: '#C0392B',
    fontSize: 12,
  },
  mediaPreview: {
    width: '100%',
    height: 220,
    borderRadius: 12,
    backgroundColor: '#1C1C1C',
  },
  photoRow: {
    flexDirection: 'row',
    gap: 8,
  },
  actions: {
    marginTop: 12,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    gap: 10,
  },
  photoPlaceholder: {
    opacity: 0.6,
  },
  mediaStrip: {
    marginTop: 6,
  },
  mediaChip: {
    width: 72,
    height: 72,
    borderRadius: 10,
    marginRight: 8,
    overflow: 'hidden',
    backgroundColor: '#E6E1D4',
    alignItems: 'center',
    justifyContent: 'center',
  },
  mediaThumb: {
    width: '100%',
    height: '100%',
  },
  videoThumb: {
    width: '100%',
    height: '100%',
    backgroundColor: '#1C1C1C',
    alignItems: 'center',
    justifyContent: 'center',
  },
  videoThumbText: {
    color: '#FFFFFF',
    fontSize: 18,
    fontWeight: '700',
  },
  mediaRemove: {
    position: 'absolute',
    top: 4,
    right: 4,
    width: 18,
    height: 18,
    borderRadius: 9,
    backgroundColor: 'rgba(0,0,0,0.6)',
    alignItems: 'center',
    justifyContent: 'center',
  },
  mediaRemoveText: {
    color: '#FFFFFF',
    fontSize: 12,
    lineHeight: 14,
    fontWeight: '700',
  },
  updateGroup: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  inlineToastText: {
    fontWeight: '700',
    fontSize: 12,
  },
});
